package cn.ms.neural.common.log;

import cn.ms.neural.common.log.impl.JdkLogFactory;
import cn.ms.neural.common.log.impl.Log4j2LogFactory;

/**
 * 日志工厂类
 * @author Looly
 *
 */
public abstract class LogFactory {
	
	private String logFramworkName;
	
	public LogFactory(String logFramworkName) {
		this.logFramworkName = logFramworkName;
	}
	
	/**
	 * 获得日志对象
	 * @param name 日志对象名
	 * @return 日志对象
	 */
	public abstract ILog getLog(String name);
	
	/**
	 * 获得日志对象
	 * @param clazz 日志对应类
	 * @return 日志对象
	 */
	public abstract ILog getLog(Class<?> clazz);
	
	//------------------------------------------------------------------------- Static start
	private static volatile LogFactory currentLogFactory;
	private static final Object lock = new Object();

	/**
	 * @return 当前使用的日志工厂
	 */
	public static LogFactory getCurrentLogFactory(){
		if(null == currentLogFactory){
			synchronized (lock) {
				if(null == currentLogFactory){
					currentLogFactory = detectLogFactory();
				}
			}
		}
		return currentLogFactory;
	}
	
	/**
	 * 自定义日志实现
	 * @param logFactory 日志工厂类
	 */
	public static void setCurrentLogFactory(LogFactory logFactory){
		logFactory.getLog(LogFactory.class).debug("Custom Use [{}] Logger.", logFactory.logFramworkName);
		currentLogFactory = logFactory;
	}
	
	public static final String BOOT_LOG = "boot-log";
	public static final String BIZ_LOG = "biz-log";
	public static final String METRICS_LOG = "metrics-log";
	public static final String PERF_LOG = "perf-log";
	public static final String ERROR_LOG = "error-log";
	//------------------------------------------------------------------------- 自定义日志 start
	/**
	 * 系统日志
	 * 
	 * @return
	 */
	public static ILog getBootLog(){
		return getCurrentLogFactory().getLog(BOOT_LOG);
	}
	/**
	 * 业务日志
	 * 
	 * @return
	 */
	public static ILog getBizLog(){
		return getCurrentLogFactory().getLog(BIZ_LOG);
	}
	/**
	 * 指标日志
	 * 
	 * @return
	 */
	public static ILog getMetricsLog(){
		return getCurrentLogFactory().getLog(METRICS_LOG);
	}
	/**
	 * 性能日志
	 * 
	 * @return
	 */
	public static ILog getPerfLog(){
		return getCurrentLogFactory().getLog(PERF_LOG);
	}
	/**
	 * 错误日志
	 * 
	 * @return
	 */
	public static ILog getErrorLog(){
		return getCurrentLogFactory().getLog(ERROR_LOG);
	}
	//------------------------------------------------------------------------- 自定义日志 end

	/**
	 * 获得日志对象
	 * @param name 日志对象名
	 * @return 日志对象
	 */
	public static ILog get(String name){
		return getCurrentLogFactory().getLog(name);
	}
	
	/**
	 * 获得日志对象
	 * @param clazz 日志对应类
	 * @return 日志对象
	 */
	public static ILog get(Class<?> clazz){
		return getCurrentLogFactory().getLog(clazz);
	}
	
	/**
	 * @return 获得调用者的日志
	 */
	public static ILog get() {
		return get(new Exception().getStackTrace()[1].getClassName());
	}
	
	/**
	 * @return 获得调用者的调用者的日志（用于内部辗转调用）
	 */
	protected static ILog indirectGet() {
		return get(new Exception().getStackTrace()[2].getClassName());
	}
	
	/**
	 * 决定日志实现
	 * @return 日志实现类
	 */
	private static LogFactory detectLogFactory(){
		LogFactory logFactory = null;
		try{
			logFactory = new Log4j2LogFactory();
			logFactory.getLog(LogFactory.class).debug("Use [{}] Logger As Default.", logFactory.logFramworkName);
		}catch(Throwable t1){
			try {
				logFactory = new JdkLogFactory();
				logFactory.getLog(LogFactory.class).debug("Use [{}] Logger As Default.", logFactory.logFramworkName);
			} catch (Throwable t2) {
			}
		}
		
		return logFactory;
	}
	//------------------------------------------------------------------------- Static end
}
